package model.game;

import model.game.skills.Punch;
import model.game.skills.Fireball;
import java.io.Serializable;
import java.util.ArrayList;
import model.game.items.LifePotion;
import model.game.skills.SmallHeal;

public class Player implements Serializable, HasInventory {
    private final double coefLife = 1.2;
    private final double coefEnergy = 1.2;
    private int id;
    private String name;
    private int life;
    private int totalLife;
    private int energy;
    private int totalEnergy;
    private int strength;
    private int intelligence;
    private int firePower;
    private int agility;
    private int resistence;
    private int vigor;
    private int armor;
    private int xp;
    private int level;
    private int aptitude;
    private int freshAtributes;
    private int totalAtributes;
    private ArrayList<Skill> skills;
    private ArrayList<Item> items;
    private int money;

    public Player(String name) {
        this.name = name;
        id = 0;
        init();
    }

    public void init() {
        level = 1;
        xp = 0;
        strength = 1;
        intelligence = 1;
        firePower = 1;
        agility = 1;
        aptitude = 1;
        resistence = 1;
        vigor = 1;
        money = 50;
        life = 15 + resistence * (int) coefLife;
        totalLife = life;
        energy = 10 + vigor * (int) coefEnergy;
        totalEnergy = energy;
        armor = 1;
        freshAtributes = 10;
        totalAtributes = 10;
        items = new ArrayList<Item>();
        items.add(new LifePotion(this, items));
        skills = new ArrayList<Skill>();
        skills.add(new Punch());
        skills.add(new Fireball());
        skills.add(new SmallHeal(this));
    }

    public int xpToLvl() {
        int xpNeeded = (int) Math.pow(2, level);
        return xpNeeded;
    }

    public boolean addXpLeveled(int x) {
        int xpNeeded = xpToLvl();
        if (xp + x >= xpNeeded) {
            addLevel();
            xp = 0;
            return true;
        } else {
            xp += x;
            return false;
        }
    }

    public void addLevel() {
        level += 1;
        totalAtributes += 3;
        freshAtributes += 3;
    }

    public ArrayList<Skill> getSkills() {
        return skills;
    }

    public void addSkill(Skill skill) {
        skills.add(skill);
    }

    public void removeSkill(Skill skill) {
        skills.remove(skill);
    }

    public int getMajorAtribute() {
        if (strength >= intelligence) {
            if (strength >= firePower) {
                return strength;
            } else {
                return firePower;
            }
        } else {
            if (intelligence >= firePower) {
                return intelligence;
            } else {
                return firePower;
            }
        }
    }

    public Skill findSkill(String str) {
        for (int i = 0; i < skills.size(); i++) {
            if (skills.get(i).getName().equals(str)) {
                return skills.get(i);
            }
        }
        return null;
    }

    public String getStrLife() {
        if (life == 100) {
            return "saudável";
        } else if (life < 100 && life >= 75) {
            return "pequenos ferimentos";
        } else if (life < 75 && life >= 50) {
            return "machucado forte";
        } else if (life < 50 && life >= 10) {
            return "sangrando";
        } else {
            return "desmaiado";
        }
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getLife() {
        return life;
    }

    public void setLife(int life) {
        if (life < 0) {
            this.life = 0;
            return;
        }
        if (life > totalLife) {
            this.life = totalLife;
            return;
        }
        this.life = life;
    }

    public int getEnergy() {
        return energy;
    }

    public void setEnergy(int energy) {
        if (energy < 0) {
            this.energy = 0;
            return;
        }
        if (energy > totalEnergy) {
            this.energy = totalEnergy;
            return;
        }
        this.energy = energy;
    }

    public int getStrength() {
        return strength;
    }

    public void setStrength(int strength) {
        if (strength >= 1) {
            this.strength = strength;
        }
    }

    public int getResistence() {
        return resistence;
    }

    public void setResistence(int resistence) {
        if (resistence >= 1) {
            this.resistence = resistence;
            int damage = totalLife - life;
            life = (15 + (int)Math.round((double)resistence * coefLife)) - damage;
            if (life < 1) {
                life = 1;
            }
            totalLife = 15 + (int)Math.round((double)resistence * coefLife);
        }
    }

    public int getAgility() {
        return agility;
    }

    public void setAgility(int agility) {
        if (agility >= 1) {
            this.agility = agility;
        }
    }

    public int getArmor() {
        return armor;
    }

    public void setArmor(int armor) {
        this.armor = armor;
    }

    public int getTotalLife() {
        return totalLife;
    }

    public void setTotalLife(int totalLife) {
        this.totalLife = totalLife;
    }

    public int getTotalEnergy() {
        return totalEnergy;
    }

    public void setTotalEnergy(int totalEnergy) {
        this.totalEnergy = totalEnergy;
    }

    public int getXp() {
        return xp;
    }

    public void setXp(int xp) {
        this.xp = xp;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public int getIntelligence() {
        return intelligence;
    }

    public void setIntelligence(int intelligence) {
        if (intelligence >= 1) {
            this.intelligence = intelligence;
        }
    }

    public int getFirePower() {
        return firePower;
    }

    public void setFirePower(int firePower) {
        if (firePower >= 1) {
            this.firePower = firePower;
        }
    }

    public int getVigor() {
        return vigor;
    }

    public void setVigor(int vigor) {
        if (vigor >= 1) {
            this.vigor = vigor;
            int lessEnergy = totalEnergy - energy;
            energy = (10 + (int)Math.round((double)vigor * coefEnergy)) - lessEnergy;
            if (energy < 1) {
                energy = 1;
            }
            totalEnergy = 10 + (int)Math.round((double)vigor * coefEnergy);
        }
    }

    public int getAptitude() {
        return aptitude;
    }

    public void setAptitude(int aptitude) {
        if (aptitude >= 1) {
            this.aptitude = aptitude;
        }
    }

    @Override
    public void addItem(Item item) {
        items.add(item);
    }

    @Override
    public void removeItem(Item item) {
        items.remove(item);
    }

    @Override
    public Item findItem(String item) {
        for (int i = 0; i < items.size(); i++) {
            if (items.get(i).getName().toLowerCase().equals(item.toLowerCase())) {
                return items.get(i);
            }
        }
        return null;
    }

    @Override
    public ArrayList<Item> getItems() {
        return items;
    }

    @Override
    public void setItems(ArrayList<Item> items) {
        this.items = items;
    }

    public int getFreshAtributes() {
        return freshAtributes;
    }

    public void setFreshAtributes(int freshAtributes) {
        if (freshAtributes < 0) {
            this.freshAtributes = 0;
        } else if (freshAtributes >= totalAtributes) {
            this.freshAtributes = totalAtributes;
        } else {
            this.freshAtributes = freshAtributes;
        }
    }

    public int getTotalAtributes() {
        return totalAtributes;
    }

    public void setTotalAtributes(int totalAtributes) {
        this.totalAtributes = totalAtributes;
    }

    public int getMoney() {
        return money;
    }

    public boolean setMoney(int money) {
        if (money < 0) {
            return false;
        } else {
            this.money = money;
            return true;
        }
    }
}
